package com.tcxhb.job.core.schedule;

import com.tcxhb.job.common.utils.DateUtils;
import com.tcxhb.job.dao.dataobject.JobInstanceDO;
import com.tcxhb.job.dao.dataobject.query.JobInstanceQuery;
import com.tcxhb.job.common.Thread.NamedThreadFactory;
import com.tcxhb.job.common.model.PageRequest;
import com.tcxhb.job.core.schedule.execute.JobRunExecutor;
import com.tcxhb.job.core.service.job.JobInstanceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @Description: 定时任务重试扫描
 * @Auther: tcxhb
 * @Date: 2023/11/7
 */
@Component
@Slf4j
public class JobRetrySchedule extends BaseScheduler implements Scheduler {
    @Autowired
    private JobRunExecutor jobRunExecutor;
    @Autowired
    private JobInstanceService jobInstanceService;
    private ScheduledExecutorService jobBeatSchedule = Executors.newScheduledThreadPool(1,
            new NamedThreadFactory("job-retry", true));
    // 间隔时间30秒扫描一次
    private Integer periodTime = 60;

    @Override
    @PostConstruct
    public void start() {
        jobBeatSchedule.scheduleAtFixedRate(() -> {
            try {
                if (isRunningServer()) {
                    Long start = System.currentTimeMillis();
                    scan();
                    Long end = System.currentTimeMillis();
                    log.info("job-retry-scan-cost:" + (end - start) / 1000);
                }
            } catch (Exception e) {
                log.error("job-retry-exp", e);
            }
        }, 20, periodTime, TimeUnit.SECONDS);
    }

    /**
     * 扫描
     */
    public void scan() {
        Long last = 0L;
        JobInstanceQuery query = buildQuery();
        while (true) {
            query.setLastId(last);
            List<JobInstanceDO> list = jobInstanceService.scan(query);
            if (CollectionUtils.isEmpty(list)) {
                break;
            }
            log.info("retry-scan-job:" + list.size());
            //遍历所有机器
            for (JobInstanceDO instanceDO : list) {
                last = instanceDO.getId();
                query.setLastId(last);
                jobRunExecutor.retry(instanceDO.getId(), false);
            }
        }
    }

    /**
     * 失败重试时间
     *
     * @return
     */
    private JobInstanceQuery buildQuery() {
        JobInstanceQuery query = new JobInstanceQuery();
        query.setPage(new PageRequest());
        query.getPage().setPageSize(5000);
        //执行失败的,包含调度失败
        query.setRetryFlag(1);
        return query;
    }
}
